/**
 * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
 */
package com.jeesite.modules.sd.service;

import com.jeesite.common.collect.ListUtils;
import com.jeesite.common.entity.Extend;
import com.jeesite.common.entity.Page;
import com.jeesite.common.mybatis.mapper.query.QueryType;
import com.jeesite.common.service.CrudService;
import com.jeesite.common.service.ServiceException;
import com.jeesite.modules.sd.common.constants.DocLogEnum;
import com.jeesite.modules.sd.common.constants.GlobalEnum;
import com.jeesite.modules.sd.common.constants.RecvConstant;
import com.jeesite.modules.sd.common.util.LogUtil;
import com.jeesite.modules.sd.common.util.ThreadPoolUtils;
import com.jeesite.modules.sd.common.vo.DocRecvAnalse;
import com.jeesite.modules.sd.dao.DocDeliverRecordDao;
import com.jeesite.modules.sd.dao.DocRecvDao;
import com.jeesite.modules.sd.entity.DocCodeDTO;
import com.jeesite.modules.sd.entity.DocDeliverRecord;
import com.jeesite.modules.sd.entity.DocRecv;
import com.jeesite.modules.sys.entity.EmpUser;
import com.jeesite.modules.sys.entity.Office;
import com.jeesite.modules.sys.service.EmpUserService;
import com.jeesite.modules.sys.service.OfficeService;
import com.jeesite.modules.sys.service.UserService;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 来文登记表Service
 *
 * @author zhanchj
 * @version 2020-06-30
 */
@Service
@Transactional(readOnly = true)
public class DocRecvService extends CrudService<DocRecvDao, DocRecv> {

    @Autowired
    @Lazy
    private DocDeliverRecordService recordService;

    @Autowired
    private OfficeService officeService;

    @Autowired
    private UserService userService;

    @Autowired
    private EmpUserService empUserService;

    @Autowired
    private DocDeliverRecordDao docDeliverRecordDao;

    @Autowired
    private DocRecvDao docRecvDao;


    /**
     * 获取单条数据
     *
     * @param docRecv
     * @return
     */
    @Override
    public DocRecv get(DocRecv docRecv) {
        return super.get(docRecv);
    }

    /**
     * 查询分页数据
     *
     * @param docRecv 查询条件
     * @return
     */
    @Override
    public Page<DocRecv> findPage(DocRecv docRecv) {
        return super.findPage(docRecv);
    }

    /**
     * 保存数据（插入或更新）
     * 会判断是否为新插入的数据,若为新插入的数据则向record表中插入一条记录
     *
     * @param docRecv
     */
    @Transactional(readOnly = false)
    public void save(DocRecv docRecv,String isProposed) {
        super.save(docRecv);

        if (docRecv.getIsNewRecord()) {
            // 插入记录到Record表中
            DocDeliverRecord record = new DocDeliverRecord();
            record.setDocId(docRecv.getId());
            //0是原件
            record.setDocCopyNo(RecvConstant.DOC_COPY_NO_ZERO);
            //分发类型 0:登记
            record.setDeliverType(GlobalEnum.RECORD_DELIVER_TYPE_REGISTER.getKey());

            recordService.save(record);
            //记录日志
            LogUtil.insertLog(docRecv, "来文登记", DocLogEnum.DOC_LOG_TYPE_REGISTER);
            //拟办
            if(isProposed.equals(GlobalEnum.DOC_IS_PROPOSED_TRUE.getKey())){
                Office office = new Office();
                Extend extend = new Extend();
                extend.setExtendS1(GlobalEnum.OFFICE_TYPE_PROPOSED.getKey());
                office.setExtend(extend);
                List<Office> list = officeService.findList(office);
                //判断是否有拟办单位
                if (CollectionUtils.isEmpty(list)) {
                    throw new ServiceException("请先设置拟办单位!");
                }
                try {
                    proposed(docRecv, list.get(0));
                }catch (Exception e){
                    throw new ServiceException("拟办出现错误!");
                }
            }
        }
    }

    /**
     * 更新状态
     *
     * @param docRecv
     */
    @Override
    @Transactional(readOnly = false)
    public void updateStatus(DocRecv docRecv) {
        super.updateStatus(docRecv);
    }

    /**
     * 删除数据
     *
     * @param docRecv
     */
    @Override
    @Transactional(readOnly = false)
    public void delete(DocRecv docRecv) {
        super.delete(docRecv);
    }

    /**
     * 拟办
     *
     * @param docRecv
     */
    @Transactional(readOnly = false,rollbackFor = Exception.class)
    public void proposed(DocRecv docRecv, Office office) {
        //设置文件状态为拟办中
        docRecv.setDocStatus(GlobalEnum.DOC_STATUS_PREPARATION.getKey());
        dao.update(docRecv);
        //新增一条拟办记录
        DocDeliverRecord record = new DocDeliverRecord();
        //设置文件拟办单位
        record.setRecvUnitCode(office.getOfficeCode());
        record.setDocId(docRecv.getId());
        //拟办文件的类型为:1分发给拟办单位
        record.setDeliverType(GlobalEnum.RECORD_DELIVER_TYPE_PROPOSED.getKey());
        //拟办的是原文件
        record.setDocCopyNo(RecvConstant.DOC_COPY_NO_ZERO);
        //保存拟办记录
        recordService.save(record);
        //添加操作日志
        LogUtil.insertLog(docRecv, "文件拟办", DocLogEnum.DOC_LOG_TYPE_PROPOSED);
    }

    /**
     * 通过单位Code查询该机构下的人
     * @param offices
     */

    @Transactional(readOnly = false)
    public List<String> selectUserByOfficeCode(List<Office> offices) {
        List<String> iphones = new ArrayList<>();
        String userCode=null;
        String  phoneNum=null;
        if (CollectionUtils.isNotEmpty(offices)){
            for (Office office:offices){
                String officeCode = office.getOfficeCode();
                EmpUser empUser = new EmpUser();
                empUser.setCodes(new String[]{officeCode});
                List<EmpUser> users = empUserService.findUserListByOfficeCodes(empUser);
                if(CollectionUtils.isEmpty(users)){
                    throw new RuntimeException("办公室没有人");
                }
                 userCode = users.get(0).getUserCode();
                 phoneNum=userService.get(userCode).getMobile();
                iphones.add(phoneNum);

            }
        }
        return iphones;

    }


    /**
     * 文件分发
     *
     * @param docRecv          分发的文件状态
     * @param offices          分发单位信息
     * @param beforeTakeDate   领取时间
     * @param beforeReturnDate 归还时间
     */
    @Transactional(readOnly = false, rollbackFor = Exception.class)
    public List<DocDeliverRecord> distribute(DocRecv docRecv, List<Office> offices, Date beforeTakeDate, Date beforeReturnDate) {
        List<DocDeliverRecord> records = ListUtils.newArrayList();
        //查询最大分发编号(二次分发时不能从1开始记录文件分发后的编号)
        int max = recordService.findMaxCopyNoByRecvId(docRecv.getId());
        StringBuilder logs = new StringBuilder();
        for (int i = 0; i < offices.size(); i++) {
            //记录前三个单位的单位名称
            if (i < 3) {
                logs.append(offices.get(i).getOfficeName()).append(",");
            }
            DocDeliverRecord deliverRecord = new DocDeliverRecord();
            deliverRecord.setBeforeTakeDate(beforeTakeDate);
            deliverRecord.setBeforeReturnDate(beforeReturnDate);
            //判断是否送文单位
            if (GlobalEnum.OFFICE_TYPE_SEND.getKey().equals(offices.get(i).getExtend().getExtendS1())) {
                deliverRecord.setDeliverType(GlobalEnum.RECORD_DELIVER_TYPE_SEND.getKey());
            }else {
                deliverRecord.setDeliverType(GlobalEnum.RECORD_DELIVER_TYPE_DELIVER.getKey());
            }
            deliverRecord.setDocId(docRecv.getId());
            //文件复制后的编号
            deliverRecord.setDocCopyNo(max+i + 1);
            //收文单位ID
            deliverRecord.setRecvUnitCode(offices.get(i).getOfficeCode());

            recordService.save(deliverRecord);

            records.add(deliverRecord);
        }
        //记录日志
        LogUtil.insertLog(docRecv,
                "分发文件给:" + logs.substring(0, logs.length() - 1) + "等单位;共计" + offices.size() + "个单位",
                DocLogEnum.DOC_LOG_TYPE_DELIVER);

        //更新来文状态为已分发
        docRecv.setDocStatus(GlobalEnum.DOC_STATUS_FINISH.getKey());
        this.dao.update(docRecv);

        return records;
    }

    /**
     * 打印当前文件分发二维码
     * @param records 文件信息
     */
    public void printCode(List<DocDeliverRecord> records) {
        //打印二维码(record中需包含来文和单位信息)
        DocRecv recv  = docDeliverRecordDao.get(records.get(0)).getDocRecv();
            try {
                records.forEach(record -> recordService.printCodeByRecord(record));
                //记录二维码打印情况
                logger.info("《{}》二维码打印完成!",recv.getDocTitle());
            } catch (Exception e) {
                logger.error("《{}》二维码打印失败,失败原因:",recv.getDocTitle(), e);

            }
    }


    /**
     * 通过ID查询当前年分该单位文件份数
     *
     * @param unitId
     * @return
     */
    public Long findCountByUnitIdAndYear(String unitId) {
        return dao.findCountByUnitIdAndYear(unitId);
    }

    /**
     * 查询当前最大sysCode
     *
     * @param unitId
     * @return
     */
    public String findMaxSysCodeByUnitId(String unitId) {
        return dao.findMaxSysCodeByUnitId(unitId);
    }



    /**
     * 分析图从来文角度 按照月份
     */
    @Transactional(readOnly = false)
    public  List<DocRecvAnalse>  recvAnalysis(String begin ,String end){

        return docRecvDao.recvAnalysis(begin ,end);

    }

    /**
     * 分析图从来文角度 按照年
     * @return
     */
    @Transactional(readOnly = false)
    public List<DocRecvAnalse> sendAnalysis(String begin,String end){
        return docRecvDao.sendAnalysis(begin,end);
    }

}